package com.tegtech.starter.redis.service;

import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * 缓存辅助类
 * 
 * @Author Jun
 * @date 2020年3月28日 下午1:18:07
 */
@Component
public class RedisCacheHelper {

	@Autowired
	private RedisCache redisCache;
	
	public static RedisCache instance;
	
	@PostConstruct
	public void init() {
		instance = this.redisCache;
	}

	/**
	 * 从缓存获取数据，若未获取到执行Supplier，获取到值后再缓存
	 * 
	 * @param key      缓存key
	 * @param time     过期时间
	 * @param supplier 若缓存未命中，获取新数据的方式
	 * @return
	 */
	public static <T> T value(String key, long time, Supplier<T> supplier) {
		T t = instance.get(key);
		if (ObjectUtil.isNull(t)) {
			t = supplier.get();
			if (ObjectUtil.isNotNull(t)) {
				instance.set(key, t, time);
			}
		}
		return t;
	}

	/**
	 * 从缓存获取数据，若未获取到执行Supplier，获取到值后再缓存
	 * 
	 * @param key      缓存key
	 * @param item     Hash键
	 * @param time     过期时间
	 * @param supplier 若缓存未命中，获取新数据的方式
	 * @return
	 */
	public static <T> T hValue(String key, String item, long time, Supplier<T> supplier) {
		T t = instance.hget(key, item);
		if (ObjectUtil.isNull(t)) {
			t = supplier.get();
			if (ObjectUtil.isNotNull(t)) {
				instance.hset(key, item, t, time);
			}
		}
		return t;
	}

	/**
	 * 从缓存获取Map数据，若未获取到执行Supplier，获取到值后再缓存
	 * 
	 * @param key      缓存key
	 * @param time     过期时间
	 * @param supplier 若缓存未命中，获取新数据的方式
	 * @return
	 */
	public static <T> Map<String, T> hmValue(String key, long time, Supplier<Map<String, T>> supplier) {
		Map<String, T> map = instance.hmget(key);
		if (CollectionUtil.isEmpty(map)) {
			map = supplier.get();
			if (CollectionUtil.isNotEmpty(map)) {
				instance.hmset(key, map, time);
			}
		}
		return map;
	}

	/**
	 * 从缓存获取list数据，若未获取到执行Supplier，获取到值后再缓存
	 * 
	 * @param key      缓存key
	 * @param time     过期时间
	 * @param supplier 若缓存未命中，获取新数据的方式
	 * @return
	 */
	public static <T> List<T> lValue(String key, long time, Supplier<List<T>> supplier) {
		List<T> list = instance.lGet(key, 0, -1);
		if (CollectionUtil.isEmpty(list)) {
			list = supplier.get();
			if (CollectionUtil.isNotEmpty(list)) {
				instance.lSet(key, list, time);
			}
		}
		return list;
	}

}
